﻿using RestSharp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Etest.Models;
using System.Xml.Serialization;
using Newtonsoft.Json;
using System.IO;

namespace Etest.Controllers
{
    public class ServerController : Controller
    {
        //
        // GET: /Server/

        public ActionResult Index()
        {
            
            ViewBag.Message = "Welcome to ASP.NET MVC!";

            string token = getAutorizationToken();
            ViewBag.token = token;

            //string images = getImageUrl(token);
            //string imageName = getImage(token).links.ElementAt(0).href;
            //string flavorName = getFlavor(token).links.ElementAt(0).href;
            //ViewBag.image = imageName;
            //ViewBag.flavor = flavorName;

            
            Image image = getImage(token);
            Flavor flavor = getFlavor(token);

            ViewBag.image = image.name;
            ViewBag.flavor = flavor.name;

            Server server = bootServer(image, flavor, token);
            ViewBag.server = server.serverInfo.id;
            
             
            //Addresses addresses = getServerIp(token, server);
            //Server server = JsonConvert.DeserializeObject<Server>("{\"server\": {\"security_groups\": [{\"name\": \"default\"}], \"OS-DCF:diskConfig\": \"MANUAL\", \"id\": \"97b072dd-a01d-435c-936e-00422832cfc0\", \"links\": [{\"href\": \"http://10.10.10.2:8774/v2/e594679e284849dcb03a709eec58841a/servers/97b072dd-a01d-435c-936e-00422832cfc0\", \"rel\": \"self\"}, {\"href\": \"http://10.10.10.2:8774/e594679e284849dcb03a709eec58841a/servers/97b072dd-a01d-435c-936e-00422832cfc0\", \"rel\": \"bookmark\"}], \"adminPass\": \"tbcCoqXB5a9g\"}}");

            //Addresses addresses = JsonConvert.DeserializeObject<Addresses>("{\"addresses\": {\"private\": [{\"version\": 4, \"addr\": \"192.168.1.4\"}, {\"version\": 4, \"addr\": \"10.10.10.130\"}]}}");
        
            //StreamReader json = new StreamReader("C:\\Users\\Stefan\\Documents\\Visual Studio 2012\\Projects\\Etest\\Etest\\App_Data\\bulk.json");
            
            //BulkFloatingIp bfi = JsonConvert.DeserializeObject<BulkFloatingIp>(json.ReadToEnd());

            ViewBag.serverIp = server.serverInfo.id;


            //moze so timer
            //this does not change anything even if two professors create test at the same time
            //write method to test when Status of virtual machine is Runnning or exists
            /*
             * while
             * {
             * System.Threading.Thread.Sleep(200) //check on every 200ms
             * 
             */
           
           // ViewBag.serverot = server;
            //moze so status Build ako e bild togas moze da se associra Ip
           //ova vreme ne zavisi od vremeto na diganje na instancata
             System.Threading.Thread.Sleep(2000);
            ViewBag.floatingIp = assignNextFreeFloatingIpToServer(token, server);

            string status="";

            //31 counts odnosno 31 sekundi da stane active 
            int counter = 0;
            do
            {
                status = getServerStatus(token, server).server.status;
                System.Threading.Thread.Sleep(2000);
                counter++;
            } while (status != "ACTIVE");

            ViewBag.status = counter;



            return View(server);
        }

        
        public string getAutorizationToken()
        {
            var client = new RestClient("http://10.10.10.2:5000/v2.0/tokens");

            var request = new RestRequest(Method.POST);

            request.AddParameter("application/json", "{\"auth\":{\"passwordCredentials\":{\"username\":\"admin\", \"password\":\"stack\"}, \"tenantId\":\"e594679e284849dcb03a709eec58841a\"}}", ParameterType.RequestBody);

            request.AddHeader("Content-Type", "application/json");
            request.RequestFormat = DataFormat.Json;

            // execute the request
            var response = client.Execute(request);
            string content = response.Content; // raw content as string*/

            //return content;

            XmlSerializer ser = new XmlSerializer(typeof(Access));
            Access xmlRootTag;

            xmlRootTag = (Access)ser.Deserialize(new StringReader(content));

            return xmlRootTag.token.id;

        }

        public string assignNextFreeFloatingIpToServer(string token, Server server)
        {
            var client = new RestClient("http://10.10.10.2:8774/v2/e594679e284849dcb03a709eec58841a/servers/" + server.serverInfo.id + "/action");
            var request = new RestRequest(Method.POST);

            var bulkIpAddresses = getAddressesFromBulk(token);

            string ip = "";
            foreach (var ipinfo in bulkIpAddresses.floating_ip_info)
            {
                if (ipinfo.instance_uuid == null)
                {
                    ip = ipinfo.address;    
                    break;
                }
            }
   
            request.AddParameter("application/json", "{\"addFloatingIp\": {\"address\":\""+ip+"\"}}", ParameterType.RequestBody);
            request.AddHeader("Content-Type", "application/json");
            request.AddHeader("X-Auth-Token", token);
            request.RequestFormat = DataFormat.Json;

            var response = client.Execute(request);

            return ip;

        }

        public BulkFloatingIp getAddressesFromBulk(string token)
        {
            var client = new RestClient("http://10.10.10.2:8774/v2/e594679e284849dcb03a709eec58841a/os-floating-ips-bulk");

            var request = new RestRequest(Method.GET);
            request.AddHeader("Content-Type", "application/json");
            request.AddHeader("X-Auth-Token", token);
            request.RequestFormat = DataFormat.Json;

            // execute the request
            var response = client.Execute(request);
            string content = response.Content; // raw content as string*/

            BulkFloatingIp bfi = JsonConvert.DeserializeObject<BulkFloatingIp>(content);

            return bfi;

        }

        public Addresses getServerIp(string token, Server server)
        {
            //moze i so server.links[0].href
            var client = new RestClient("http://10.10.10.2:8774/v2/e594679e284849dcb03a709eec58841a/servers/"+server.serverInfo.id+"/ips");

            var request = new RestRequest(Method.GET);
            request.AddHeader("Content-Type", "application/json");
            request.AddHeader("X-Auth-Token", token);
            request.RequestFormat = DataFormat.Json;

            // execute the request
            var response = client.Execute(request);
            string content = response.Content; // raw content as string*/

            Addresses addresses = JsonConvert.DeserializeObject<Addresses>(content);
    

            return addresses;
        }

        public ServerStatus getServerStatus(string token, Server server)
        {
            var client = new RestClient("http://10.10.10.2:8774/v2/e594679e284849dcb03a709eec58841a/servers/" + server.serverInfo.id);
            var request = new RestRequest(Method.GET);
            request.AddHeader("Content-Type", "application/json");
            request.AddHeader("X-Auth-Token", token);
            request.RequestFormat = DataFormat.Json;

            // execute the request
            var response = client.Execute(request);
            string content = response.Content; // raw content as string*/

            ServerStatus serverstatus = JsonConvert.DeserializeObject<ServerStatus>(content);

            return serverstatus;
        }

        public Server bootServer(Image image, Flavor flavor, string token)
        {
            var client = new RestClient("http://10.10.10.2:8774/v2/e594679e284849dcb03a709eec58841a/servers");

            string sName = "AssessmentNodeTemp";
            string sImageRef = image.links.ElementAt(0).href;
            string sFlavorRef = flavor.links.ElementAt(0).href;
            string sMetadata = "{}";
            string sPersonalityPath = "";
            string sPersonalityContents = "";
            string sPersonality = "[ { \"path\":" + sPersonalityPath + ", \"contents\":base64.b64encode( " + sPersonalityContents + " ) } ]";
            //string s = "{ \"server\": { \"name\": "+sName+", \"imageRef\": "+sImageRef+", \"flavorRef\": "+sFlavorRef+", \"metadata\": "+sMetadata+", \"personality\": "+sPersonality+" } }";

            string s = "{\"server\": {\"flavorRef\": \"" + sFlavorRef + "\", \"personality\": [{\"path\": \"\", \"contents\": \"\"}], \"name\": \"AssessmentNodeTemp\", \"imageRef\": \"" + sImageRef + "\", \"metadata\": {\"Server Name\": \"AssessmentNodeTemp\"}}}";

            var request = new RestRequest(Method.POST);

            request.AddParameter("application/json", s, ParameterType.RequestBody);

            request.AddHeader("Content-Type", "application/json");
            request.AddHeader("X-Auth-Token", token);
            request.RequestFormat = DataFormat.Json;

            // execute the request
            var response = client.Execute(request);
            string content = response.Content; // raw content as string*/

            Server server = JsonConvert.DeserializeObject<Server>(content);

            return server;
        }

        public Image getImage(string token)
        {
            var client = new RestClient("http://10.10.10.2:8774/v2/e594679e284849dcb03a709eec58841a/images");

            var request = new RestRequest(Method.GET);

            request.AddHeader("Content-Type", "application/json");
            request.AddHeader("X-Auth-Token", token);
            request.RequestFormat = DataFormat.Json;

            // execute the request
            var response = client.Execute(request);
            string content = response.Content; // raw content as string*/

            ImageGroup imageGroup = JsonConvert.DeserializeObject<ImageGroup>(content);

            //ova moze da se customizira
            foreach (Image i in imageGroup.images)
            {
                if (i.name.Equals("AssessNodeSnapShot"))
                {
                    return i;
                }
            }

            return null;
        }

        public Flavor getFlavor(string token)
        {
            var client = new RestClient("http://10.10.10.2:8774/v2/e594679e284849dcb03a709eec58841a/flavors");

            var request = new RestRequest(Method.GET);

            request.AddHeader("Content-Type", "application/json");
            request.AddHeader("X-Auth-Token", token);
            request.RequestFormat = DataFormat.Json;

            // execute the request
            var response = client.Execute(request);
            string content = response.Content; // raw content as string*/

            FlavorGroup flavorGroup = JsonConvert.DeserializeObject<FlavorGroup>(content);

            //ova moze da se customizira spored brojot na useri
            foreach (Flavor i in flavorGroup.flavors)
            {
                if (i.name.Equals("m1.small"))
                {
                    return i;
                }
            }

            return null;
        }

    }
}
